﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Collections.ObjectModel;
using System.Threading;
using MP3Ganizer.DAL;

namespace MP3Ganizer.Services.Files
{
    public class FilesServices
    {

        public static void GetTagsFromDirectory(ObservableCollection<object> tagFiles, string path, out int total)
        {
            total = 0;
            try
            {
                List<string> files = Directory.GetFiles(path, "*.*", SearchOption.AllDirectories).ToList<string>();
                total = files.Count;
                files.ForEach(x => AddTagFile(tagFiles, x));
            }
            catch
            {
                //TODO
            }
        }

        private static void AddTagFile(ObservableCollection<object> tagFiles, string file)
        {
            try
            {
                TagLib.File f = TagLib.File.Create(file);
                tagFiles.Add(f);


            }
            catch
            {
                if (!file.ToLower().EndsWith(".db") && !file.ToLower().EndsWith(".ini"))
                    tagFiles.Add(file);
            }
            

        }

        public static string GetDestinationPathFromSource(TagLib.File file, string albumArtist, string album, string destination, string name, string mask)
        {
            string path;
            if (file != null)
                path = GetDestinationPathFromSource(file, destination, mask);
            else
                path = GetDestinationPathFromSource(albumArtist, album, destination, name, mask);
            return path;

        }
        private static string RemoveForbiddenChar(string originalStr)
        {
             List<string> forbidden = (new string[11] { "\\", "/", ":", "*", "?", "\"", "<", ">", "|", ".", "_"}).ToList<string>();
            forbidden.ForEach(c =>
            {
                if (originalStr != null)
                    originalStr = originalStr.Replace(c, string.Empty);
            }
            );
            return originalStr;
        }
        private static string GetDestinationPathFromSource(string albumArtist, string album, string destination, string name, string mask)
        {
            albumArtist = RemoveForbiddenChar(albumArtist);
            album= RemoveForbiddenChar(album);
            name = RemoveForbiddenChar(name);

            string destDir = string.Concat(destination, "\\");
            if(!string.IsNullOrEmpty(albumArtist))
                destDir = string.Concat(destDir, albumArtist, "\\");
            if (!string.IsNullOrEmpty(album))
                destDir = string.Concat(destDir, album, "\\");
            string destFile = string.Concat(destDir, name);
            return destFile;
        }


        private static string GetDestinationPathFromSource(TagLib.File file, string destination, string mask)
        {
            string firstAlbumArtist = RemoveForbiddenChar(file.Tag.FirstAlbumArtist);
            string album = RemoveForbiddenChar(file.Tag.Album);
            string title = file.Tag.Title != null ? file.Tag.Title.Replace('\\', '_') : "";
            string destFile = RemoveForbiddenChar(title);
            string destDir = string.Concat(destination, "\\", firstAlbumArtist , "\\", album, "\\");
            if(file.Tag.Track != 0)
                destFile = string.Concat(file.Tag.Track, " - ", destFile, ".", file.Name.Split('.').Last<string>());
            else
                destFile = string.Concat(destFile, ".", file.Name.Split('.').Last<string>());  
            destFile = string.Concat(destDir, destFile);
            return destFile;
        }

        public static string CopyToDestination(string sourcePath, string destinationPath)
        {
            string msg = string.Empty;
            try
            {
                FileInfo destinationInfo = new FileInfo(destinationPath);

                if (!System.IO.Directory.Exists(destinationInfo.DirectoryName))
                    System.IO.Directory.CreateDirectory(destinationInfo.DirectoryName);
                if (System.IO.File.Exists(destinationPath))
                    System.IO.File.Delete(destinationPath);
                if (!System.IO.File.Exists(destinationPath) && System.IO.Directory.Exists(destinationInfo.DirectoryName) && System.IO.File.Exists(sourcePath))
                {
                    System.IO.File.Copy(sourcePath, destinationPath);
                    Delete(sourcePath);
                }
            }
            catch(Exception e)
            {
                msg = e.Message;
            }
            return msg;
        }

        private static void Delete(string sourcePath)
        {
            try
            {
                System.IO.File.Delete(sourcePath);
            }
            catch(Exception e)
            {
                System.Windows.MessageBox.Show(e.Message);
            }
        }

        public static List<string> UpdateAndGetSortedArtistList(List<string> list)
        {
            list.ForEach(x => Query.Instance.TryInsertArtiste(x));
            List<string> artists = Query.Instance.GetAllArtiste();
            artists.Sort();
            return artists;
        }

        public static List<string> UpdateAndGetSortedAlbumList(Dictionary<string, string> dictionnary)
        {
            dictionnary.Keys.ToList<string>().ForEach(x => Query.Instance.TryInsertAlbum(x, dictionnary[x]));
            List<string> albums = Query.Instance.GetAllAlbum();
            albums.Sort();
            return albums;
        }

        public static void CleanEmptyDirectories(string sourceDir)
        {
            System.IO.DirectoryInfo dirInfo = new DirectoryInfo(sourceDir);
            List<DirectoryInfo> subDirectories = dirInfo.GetDirectories("*", SearchOption.TopDirectoryOnly).ToList<DirectoryInfo>();
            subDirectories.ForEach(d =>
                {
                    List<FileInfo> inutils = d.GetFiles("desktop.ini",SearchOption.AllDirectories).ToList<FileInfo>();
                    inutils.AddRange(d.GetFiles("Thumbs.db", SearchOption.AllDirectories).ToList<FileInfo>());
                    if (inutils.Count > 0)
                        inutils.ForEach(f => f.Delete());
                    if (d.GetFiles("*",SearchOption.AllDirectories).Count<FileInfo>() == 0)
                        d.Delete(true);
                }
            );
        }
    }
}
